package com.lagou.handler;

import com.alibaba.fastjson.JSONObject;
import com.lagou.boot.SpringContextHolder;
import com.lagou.entity.RpcRequest;
import com.lagou.serializer.JSONSerializer;
import com.lagou.service.UserServiceImpl;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.commons.beanutils.ConvertUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zy
 * @version 1.0
 * @date 2021/1/25 23:12
 */
public class UserServiceHandler extends ChannelInboundHandlerAdapter {


    // 当客户端读取数据的时候，该方法会被调用
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //注意:  客户端将来发送请求的时候会传递一个RpcRequest对象
        //1.判断当前的请求是否符合规则
        if ( msg != null ){
            // 获得rpcRequest对象
            RpcRequest rpcRequest = JSONObject.parseObject(msg.toString(), RpcRequest.class);
            // 获取类路径
            String className = rpcRequest.getClassName();
            // 获取方法名称
            String methodName = rpcRequest.getMethodName();
            // 获得参数
            Object[] parameters = rpcRequest.getParameters();
            // 获得参数类型
            Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
            // 获得UserServiceImpl
            Object bean = SpringContextHolder.getBean(rpcRequest.getRequestId());
            // 得到方法
            Method method = getMethod(bean.getClass(), methodName);
            // 获取参数
            List<Object> methodParamList = getMethodParamList(parameters, parameterTypes);
            // 调用方法
            Object invoke = method.invoke(bean, methodParamList);
            // 把结果输出给客户端
            ctx.writeAndFlush(invoke);
        }
    }

    /**
     * 获取方法实际参数，不支持基本类型
     */
    private List<Object> getMethodParamList(Object[] paramMap, Class<?>[] parameterTypes) throws Exception {
        List<Object> objectList = new ArrayList<>();
        for (int i = 0; i < paramMap.length; i++) {
            Object convert = ConvertUtils.convert(paramMap[i], parameterTypes[i]);
            objectList.add(convert);
        }
        return objectList;
    }

    /**
     * 获取目标方法
     * @param proxyObject
     * @param methodStr
     * @return
     */
    private Method getMethod(Class proxyObject, String methodStr) {
        Method[] methods = proxyObject.getMethods();
        for(Method method : methods) {
            if(method.getName().equalsIgnoreCase(methodStr)) {
                return method;
            }
        }
        return null;
    }

//    // 当客户端读取数据的时候，该方法会被调用
//    @Override
//    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        //注意:  客户端将来发送请求的时候会传递一个参数:  UserService#sayHello#are you ok
//        //1.判断当前的请求是否符合规则
//        if ( msg.toString().startsWith("UserService") ){
//            //2.如果符合规则,调用实现类货到一个result
//            UserServiceImpl userService = new UserServiceImpl();
//            String s = userService.sayHello(msg.toString().substring(msg.toString().lastIndexOf("#" )+ 1));
//            //3.把调用实现类的方法获得的结果写到客户端
//            ctx.writeAndFlush(s);
//        }
//    }
}
